﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LogicBaseLibrary.Zip
{
    public class zipHeader
    {
        private byte[] Type = new byte[] { 64, 67, 90 };
        private int HeaderSize = 0;
        private List<FileItem> fileItems = null;

        public List<FileItem> FileItems
        {
            get { return fileItems; }
        }

        public zipHeader()
        {
            fileItems = new List<FileItem>();
        }
        
        public void AddFile(FileItem fi)
        {
            fi.Index = this.fileItems.Count;
            this.fileItems.Add(fi);
        }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            
            foreach (FileItem fi in fileItems)
            {
                sb.AppendFormat("{0}\r", fi.ToString());
            }
            sb.Append((char)34);
            return sb.ToString();
        }

        public byte[] ToByte()
        {
            List<byte> Bytelist = new List<byte>(Type);
            Bytelist.AddRange(BitConverter.GetBytes(HeaderSize));
            StringBuilder sb = new StringBuilder();
            foreach (FileItem fi in fileItems)
            {
                Bytelist.AddRange(fi.ToBytes());
            }
            Bytelist.Add(22);
            this.HeaderSize = Bytelist.Count;
            byte[] bytes = BitConverter.GetBytes(this.HeaderSize);
            Bytelist[3] = bytes[0];
            Bytelist[4]=bytes[1];
            Bytelist[5]=bytes[2];
            Bytelist[6]=bytes[3];
            return Bytelist.ToArray();
        }

        public static zipHeader FromeByte(byte[] buffer)
        {
            zipHeader header = new zipHeader();
            
            if (buffer[buffer.Length - 1] == 22)
            {
                int lastFileIndex = 0;
                string name = string.Empty;
                string path = string.Empty;
                long uncompresslength = 0;
                long compresslength = 0;
                FileItem fi = null;
                byte[] tmpBuffer = null;
                int fieldlength = 0;

                while (lastFileIndex < buffer.Length - 1)
                {
                    // get file name
                    tmpBuffer = new byte[4];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += 4;
                    fieldlength = BitConverter.ToInt32(tmpBuffer, 0);
                    tmpBuffer = new byte[fieldlength];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += fieldlength;
                    name = Encoding.UTF8.GetString(tmpBuffer);

                    //get file path
                    tmpBuffer = new byte[4];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += 4;
                    fieldlength = BitConverter.ToInt32(tmpBuffer, 0);
                    tmpBuffer = new byte[fieldlength];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += fieldlength;
                    path = Encoding.UTF8.GetString(tmpBuffer);

                    //get compresslength
                    tmpBuffer = new byte[8];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += 8;
                    compresslength = BitConverter.ToInt64(tmpBuffer, 0);

                    //get uncompresslength
                    tmpBuffer = new byte[8];
                    Array.Copy(buffer, lastFileIndex, tmpBuffer, 0, tmpBuffer.Length);
                    lastFileIndex += 8;
                    uncompresslength = BitConverter.ToInt64(tmpBuffer, 0);

                    fi = new FileItem(name, path, compresslength, uncompresslength);
                    header.AddFile(fi);
                }

                
            }
            return header;
        }
    }
}
